package com.slowfly.rule.engine.util;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;

import java.util.HashMap;
import java.util.Map;

public class GroovyScriptUtil {

    public static Map<String, GroovyObject> passedClassMap = new HashMap<>();

    public static GroovyClassLoader groovyClassLoader;

    static {
        groovyClassLoader = new GroovyClassLoader(AutowiredAnnotationBeanPostProcessor.class.getClassLoader());
    }

    /**
     * 加载 groovy script.
     */
    public static synchronized GroovyObject loadScript(String script) throws InstantiationException, IllegalAccessException {
        GroovyObject groovyObject = passedClassMap.get(CryptUtils.md5(script));
        if (groovyObject == null) {
            Class<?> groovyClass = groovyClassLoader.parseClass(script);
            groovyObject = (GroovyObject) groovyClass.newInstance();
            passedClassMap.put(CryptUtils.md5(script), groovyObject);
        }
        return groovyObject;
    }

    public static Object invokeMethod(GroovyObject object, String method, Object[] args) {
        return object.invokeMethod(method, args);
    }

    public static Object invokeMethod(String script, String method, Object[] args) throws InstantiationException, IllegalAccessException {
        GroovyObject groovy = loadScript(script);
        return invokeMethod(groovy, method, args);
    }

    /**
     * 删除不在使用的脚本关联的groovy object, 不然内存有溢出风险。
     */
    public static void removeInactiveScript(String script) {
        passedClassMap.remove(CryptUtils.md5(script));
    }
}
